<template>
	<div>
		<!--  编辑弹框-->
		<el-dialog v-if="dialogVisible" :model-value="dialogVisible" :show-close="false" :before-close="handleClose" width="70%">
			<template #header="{ titleId, titleClass }">
				<div class="my-header">
					<h4 :id="titleId" :class="titleClass">{{ headerTitle }}</h4>
					<el-button type="danger" plain size="small" class="custom-close-btn" @click="handleSilentClose">
						<el-icon :size="16"><Close /></el-icon>
					</el-button>
				</div>
			</template>
			<el-form ref="ruleFormRef" :model="form" :rules="rules" label-width="120px" class="ruleForm" :size="formSize" status-icon>
				<el-form-item label="套装名称" prop="name">
					<el-input v-model="form.name" />
				</el-form-item>

				<el-form-item label="套装属性" prop="attribute">
					<div class="common-container">
						<div class="common-inputs">
							<el-select v-model="tempAttribute.name" placeholder="选择属性" class="common-select">
								<el-option v-for="attr in attributeOptions" :key="attr.value" :label="attr.label" :value="attr.value" />
							</el-select>
							<el-input v-model="tempAttribute.value" placeholder="输入数值" type="number" class="common-number-input" />
							<el-button type="primary" class="common-add-btn" @click="addAttribute"> 添加属性 </el-button>
						</div>

						<div class="common-list">
							<div v-for="(attr, index) in form.attribute" :key="index" class="common-item">
								<span class="item-text"> {{ getAttributeLabel(attr.name) }}: {{ attr.value }} </span>
								<el-button type="danger" size="small" :icon="Delete" class="item-del-btn" @click="removeAttribute(index)" />
							</div>
						</div>
					</div>
				</el-form-item>

				<el-form-item label="套装效果" prop="effect">
					<div class="common-container">
						<div class="common-inputs">
							<el-select v-model="tempEffect.piece" placeholder="选择件数" class="common-select">
								<el-option v-for="n in 5" :key="n" :label="`拥有${n}件`" :value="n" />
							</el-select>
							<el-input v-model="tempEffect.description" placeholder="输入效果描述" class="common-description-input" />
							<el-button type="primary" class="common-add-btn" @click="addEffect"> 添加效果 </el-button>
						</div>

						<div class="common-list">
							<div v-for="(eff, index) in sortedEff" :key="index" class="common-item">
								<span class="item-text">拥有{{ eff.piece }}件: {{ eff.description }}</span>
								<el-button type="danger" size="small" :icon="Delete" class="item-del-btn" @click="removeEffect(index)" />
							</div>
						</div>
					</div>
				</el-form-item>

				<el-form-item label="品级" prop="grade">
					<el-select v-model="form.grade" placeholder="请选择品级" clearable>
						<el-option v-for="item in gradeOptions" :key="item.value" :label="item.label" :value="item.value" />
					</el-select>
				</el-form-item>

				<el-form-item label="套装详情" prop="content">
					<TiptapEditor v-model="form.content" class="editor-container" style="min-height: 500px" />
				</el-form-item>
			</el-form>
			<template #footer>
				<span class="dialog-footer">
					<el-button @click="handleResetForm(ruleFormRef)">取消</el-button>
					<el-button type="primary" @click="handleSubmitForm(ruleFormRef)">提交</el-button>
				</span>
			</template>
		</el-dialog>

		<el-row>
			<!--  分页查询表单按钮-->
			<el-col>
				<el-form :inline="true">
					<!--        查询输入框-->
					<el-row>
						<el-col>
							<el-form-item label-width="5px">
								<el-input v-model="name" placeholder="输入装备名称" />
							</el-form-item>
							<el-form-item label="所属类型">
								<el-select v-model="belongFilter" placeholder="全部类型" clearable style="width: 100px">
									<el-option v-for="item in belongOptions" :key="item.value" :label="item.label" :value="item.value" />
								</el-select>
							</el-form-item>
							<el-form-item label-width="5px">
								<el-button type="primary" :icon="Search" @click="load"> 查询 </el-button>
								<el-button type="warning" :icon="Refresh" @click="handleReset"> 重置 </el-button>
							</el-form-item>
						</el-col>
					</el-row>
				</el-form>
			</el-col>
			<!-- 新增和批量按钮 -->
			<el-col style="margin-bottom: 10px; display: flex; gap: 10px">
				<!--   新增   -->
				<div v-permission="'sys:suit:add'">
					<el-button type="primary" :icon="Plus" size="small" plain @click="handleAdd"> 新增 </el-button>
				</div>
				<!--   批量导入   -->
				<div v-permission="'sys:suit:batch:upload'">
					<el-upload action="" :before-upload="beforeBatchUpload" :show-file-list="true">
						<el-button type="success" :icon="Upload" size="small" plain> 批量导入 </el-button>
					</el-upload>
				</div>
				<!--   批量删除   -->
				<div v-permission="'sys:suit:batch:delete'">
					<el-popconfirm
						confirm-button-text="确定"
						cancel-button-text="取消"
						:icon="InfoFilled"
						icon-color="#626AEF"
						title="确认要批量删除吗？"
						@confirm="handleBatchDel"
						@cancel="load"
					>
						<template #reference>
							<el-button type="danger" :disabled="disabled" :icon="Delete" size="small" plain> 批量删除 </el-button>
						</template>
					</el-popconfirm>
				</div>

				<div v-permission="'sys:suit:batch:export'">
					<el-button type="warning" :icon="Download" :disabled="disabled" size="small" plain @click="handleBatchExport"> 批量导出 </el-button>
				</div>
			</el-col>
			<!--  表格页面-->
			<el-col>
				<el-table
					:data="tableData"
					style="width: 100%"
					:header-cell-style="{ background: '#eef1f6', color: '#606266' }"
					@selection-change="handleSelectionChange"
				>
					<el-table-column type="selection" width="55" />
					<el-table-column prop="id" label="ID" align="center" sortable />
					<el-table-column prop="name" label="套装名称" align="center" show-overflow-tooltip />
					<el-table-column label="套装属性" align="center" width="120">
						<template #default="scope">
							<el-popover v-if="scope.row.attribute.length" placement="right" width="300" trigger="click">
								<template #reference>
									<el-link type="primary"> 点击查看({{ scope.row.attribute.length }}) </el-link>
								</template>
								<div class="attribute-list">
									<div v-for="(attr, index) in scope.row.attribute" :key="index" class="attribute-item">
										{{ getAttributeLabel(attr.name) }}: +{{ attr.value }}
									</div>
								</div>
							</el-popover>
							<span v-else>-</span>
						</template>
					</el-table-column>

					<el-table-column label="套装效果" align="center" width="120">
						<template #default="scope">
							<el-popover v-if="scope.row.effect?.length" placement="right" width="400" trigger="click">
								<template #reference>
									<el-link type="primary"> 点击查看({{ scope.row.effect.length }}) </el-link>
								</template>
								<div class="effect-list">
									<div v-for="(eff, index) in sortedEffects(scope.row.effect)" :key="index" class="effect-item">
										拥有{{ eff.piece }}件: {{ eff.description }}
									</div>
								</div>
							</el-popover>
							<span v-else>-</span>
						</template>
					</el-table-column>
					<el-table-column prop="grade" label="品级" align="center">
						<template #default="scope">
							{{ getGradeLabel(scope.row.grade) }}
						</template>
					</el-table-column>

					<el-table-column label="操作" align="center" width="240">
						<template #default="scope">
							<div style="display: flex; justify-content: center; gap: 10px">
								<div>
									<el-button v-permission="'sys:equip:update'" type="primary" :icon="Edit" size="small" @click="handleUpdate(scope.row.id)">
										编辑
									</el-button>
								</div>
								<div v-permission="'sys:equip:delete'">
									<el-popconfirm
										confirm-button-text="确定"
										cancel-button-text="取消"
										:icon="InfoFilled"
										icon-color="#626AEF"
										title="确认要删除吗？"
										@confirm="handleDel(scope.row.id)"
										@cancel="load"
									>
										<template #reference>
											<el-button type="danger" :icon="Delete" size="small"> 删除 </el-button>
										</template>
									</el-popconfirm>
								</div>
							</div>
						</template>
					</el-table-column>
				</el-table>
				<!--      分页按钮-->
				<div class="pagination">
					<el-pagination
						:current-page="pageNum"
						:page-size="pageSize"
						:page-sizes="[10, 20, 30, 50, 100, 500, 1000]"
						size="small"
						layout="total, sizes, prev, pager, next, jumper"
						:total="Number(total)"
						@size-change="handleSizeChange"
						@current-change="handleCurrentChange"
					/>
				</div>
			</el-col>
		</el-row>
	</div>
</template>

<script setup>
import { computed, onBeforeUnmount, reactive, ref, shallowRef } from 'vue'
import { CircleCloseFilled, Close, Delete, Download, Edit, InfoFilled, Plus, Refresh, Search, Upload } from '@element-plus/icons-vue'
import request from '@/utils/request'
import { ElMessage, ElMessageBox } from 'element-plus'
import downloadExcel from '@/utils/downloads'
import 'md-editor-v3/lib/style.css'
import router from '@/router'
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
import '@wangeditor/editor/dist/css/style.css'
import TiptapEditor from '@/components/tiptap/TiptapEditor.vue'

const headerTitle = ref()
const pageNum = ref(1)
const pageSize = ref(10)
const total = ref(0)
const tableData = ref([])
const multipleSelection = ref([])
const disabled = ref(true)
const dialogVisible = ref(false)
const name = ref('')
const belongFilter = ref('')
const formSize = ref('default')
const ruleFormRef = ref()
const $route = router

const tempAttribute = reactive({
	name: '',
	value: ''
})

const tempEffect = reactive({
	piece: '',
	description: ''
})

const attributeOptions = ref([
	{ value: 'aggressivity', label: '攻击' },
	{ value: 'critical', label: '暴击率' },
	{ value: 'defense', label: '防御' },
	{ value: 'health', label: '生命上限' },
	{ value: 'mana', label: '法力上限' },
	{ value: 'physical', label: '气力上限' },
	{ value: 'poison', label: '毒伤耐性' },
	{ value: 'mine', label: '雷蛰耐性' },
	{ value: 'fire', label: '火焚耐性' },
	{ value: 'ice', label: '寒冻耐性' }
])

const gradeOptions = ref([
	{ value: 1, label: '凡品' },
	{ value: 2, label: '良品' },
	{ value: 3, label: '上品' },
	{ value: 4, label: '特品' },
	{ value: 5, label: '仙品' },
	{ value: 6, label: '神珍' }
])

const belongOptions = ref([
	{ value: 1, label: '兵器' },
	{ value: 2, label: '葫芦' },
	{ value: 3, label: '头冠' },
	{ value: 4, label: '臂甲' },
	{ value: 5, label: '衣甲' },
	{ value: 6, label: '腿甲' },
	{ value: 7, label: '珍玩' },
	{ value: 8, label: '精魄' }
])

const form = reactive({
	id: undefined,
	name: undefined,
	attribute: [],
	effect: [],
	belong: undefined
})

const rules = reactive({
	name: [{ required: true, message: '必选项不能为空', trigger: 'blur' }],
	belong: [{ required: true, message: '必选项不能为空', trigger: 'change' }]
})

const handleSilentClose = () => {
	handleResetForm(ruleFormRef.value)
	dialogVisible.value = false
}

const addEffect = () => {
	if (!tempEffect.piece || !tempEffect.description) {
		ElMessage.warning('请选择件数并输入效果描述')
		return
	}

	// 检查是否已存在相同件数
	const exists = form.effect.some(eff => eff.piece === tempEffect.piece)
	if (exists) {
		ElMessage.warning('该件数效果已存在')
		return
	}

	form.effect.push({
		piece: Number(tempEffect.piece),
		description: tempEffect.description
	})

	tempEffect.piece = ''
	tempEffect.description = ''
}

const removeEffect = index => {
	form.effect.splice(index, 1)
}

const sortedEff = computed(() => {
	return [...form.effect].sort((a, b) => a.piece - b.piece)
})

const sortedEffects = effects => {
	return [...effects].sort((a, b) => a.piece - b.piece)
}

//新增方法
const handleAdd = async () => {
	headerTitle.value = reactive('新增数据')
	dialogVisible.value = true
}

// 修改方法
const handleUpdate = async id => {
	dialogVisible.value = true
	headerTitle.value = '编辑数据'
	const res = await request.get(`/suit/${id}`)

	const attributes = res.data.attribute ? res.data.attribute.flatMap(map => Object.entries(map).map(([name, value]) => ({ name, value }))) : []

	Object.assign(form, {
		...res.data,
		attribute: attributes
	})
	console.log(attributes)
}

// 单个删除方法
const handleDel = async id => {
	await request.delete(`/suit/${id}`)
	ElMessage({
		showClose: true,
		message: '删除成功',
		type: 'success'
	})
	await load()
}
// 批量删除方法
const handleBatchDel = async () => {
	const ids = []
	multipleSelection.value.forEach(row => {
		ids.push(row.id)
	})
	await request.delete(`/suit/batch/${ids}`)
	ElMessage({
		showClose: true,
		message: '批量删除成功',
		type: 'success'
	})
	await load()
}

// 分页查询方法（初始化方法，页面加载成功以后就调用的方法）
const load = async () => {
	const res = await request.get('/suit/page', {
		params: {
			pageNum: pageNum.value,
			pageSize: pageSize.value,
			name: name.value,
			belong: belongFilter.value
		}
	})
	pageNum.value = res.data.current
	pageSize.value = res.data.size
	total.value = res.data.total
	tableData.value = res.data.records.map(item => {
		const attributes = item.attribute ? item.attribute.flatMap(map => Object.entries(map).map(([name, value]) => ({ name, value }))) : []

		return {
			...item,
			attribute: attributes
		}
	})
}

const addAttribute = () => {
	if (!tempAttribute.name || !tempAttribute.value) {
		ElMessage.warning('请选择属性并输入数值')
		return
	}

	form.attribute.push({
		name: tempAttribute.name,
		value: Number(tempAttribute.value)
	})

	tempAttribute.name = ''
	tempAttribute.value = ''
}

const removeAttribute = index => {
	form.attribute.splice(index, 1)
}

// 清空查询数据重置方法
const handleReset = () => {
	name.value = ''
	belongFilter.value = ''
	load()
}
// 修改每页展示的数据量方法
const handleSizeChange = size => {
	pageSize.value = size
	load()
}
// 翻页方法
const handleCurrentChange = current => {
	pageNum.value = current
	load()
}
// 多选按钮处理方法
const handleSelectionChange = val => {
	multipleSelection.value = val
	disabled.value = val.length === 0
}

const getAttributeLabel = value => {
	const item = attributeOptions.value.find(item => item.value === value)
	return item?.label || `未定义属性(${value})`
}

// 关闭弹框提示方法
const handleClose = done => {
	ElMessageBox.confirm('确定关闭窗口?')
		.then(() => {
			handleResetForm(ruleFormRef.value)
		})
		.then(() => {
			done()
		})
		.catch(() => {
			// catch error
		})
}

const getGradeLabel = value => {
	const item = gradeOptions.value.find(item => item.value === value)
	return item ? item.label : '未知品级'
}

const formatJson = json => {
	try {
		const obj = JSON.parse(json)
		return Object.keys(obj).join(', ')
	} catch {
		return '无效格式'
	}
}

// 提交表单校验方法
const handleSubmitForm = async formEl => {
	if (!formEl) {
		return
	}

	await formEl.validate(async (valid, fields) => {
		if (valid) {
			const attributeList = form.attribute.map(attr => {
				return { [attr.name]: Number(attr.value) }
			})

			const effectList = form.effect.map(eff => ({
				piece: eff.piece,
				description: eff.description
			}))

			const submitData = {
				...form,
				attribute: attributeList,
				effect: effectList
			}

			await request({
				method: form.id ? 'put' : 'post',
				url: form.id ? `/suit/${form.id}` : '/suit',
				data: submitData
			})
			ElMessage({
				showClose: true,
				message: '操作成功',
				type: 'success'
			})
			await handleResetForm(formEl)
		} else {
			console.log('error submit!', fields)
		}
	})
}
// 批量导入读数据写到后端数据库中
const beforeBatchUpload = async file => {
	let fd = new FormData()
	fd.append('file', file)
	await request.post('/suit/batch/upload', fd, {
		headers: {
			'Content-Type': 'multipart/form-data'
		}
	})
	ElMessage({
		showClose: true,
		message: '上传成功',
		type: 'success'
	})
	await load()
}
// 批量导出方法
const handleBatchExport = async () => {
	const ids = multipleSelection.value.map(row => row.id)
	const res = await request(
		{
			url: `/suit/batch/export/${ids}`,
			method: 'get',
			responseType: 'blob'
		} //在请求中加上这一行，特别重要
	)
	downloadExcel(res, '导出数据表')
}
// 取消弹框方法
const handleResetForm = async formEl => {
	if (!formEl) {
		return
	}
	formEl.resetFields()

	Object.assign(form, {
		id: undefined,
		name: undefined,
		img: undefined,
		aggressivity: 0,
		critical: 0,
		defense: 0,
		mana: 0,
		fire: 0,
		ice: 0,
		drug: 0,
		thunder: 0
	})
	// formEl.clearValidate("img")
	dialogVisible.value = false
	await load()
}

// 文件上传方法
const uploadimg = async file => {
	let fd = new FormData()
	fd.append('file', file)
	const res = await request.post('/file/upload', fd, {
		headers: {
			'Content-Type': 'multipart/form-data'
		}
	})
	ElMessage({
		showClose: true,
		message: '上传成功',
		type: 'success'
	})
	form.img = res.data
	ruleFormRef.value.clearValidate('img')
}

// 文件下载
const dowload = async url => {
	window.open(url)
}
// 富文本文件上传
const onUploadImg = async (files, callback) => {
	let i = 0
	const res = await Promise.all(
		files.map(file => {
			if (i > 0) {
				return false
			}
			return new Promise((rev, rej) => {
				const formdata = new FormData()
				formdata.append('file', file)

				request
					.post('/file/upload', formdata, {
						headers: {
							'Content-Type': 'multipart/form-data'
						}
					})
					.then(res => {
						i++
						rev(res.data)
					})
					.catch(error => rej(error))
			})
		})
	)
	callback(res)
}

load()
</script>

<style scoped lang="scss">
.el-form--inline .el-form-item {
	margin-right: 10px;
}

.form_header {
	background-color: #666666;
}

.pagination {
	margin-top: 10px;
}

.my-header {
	display: flex;
	flex-direction: row;
	justify-content: space-between;
}

.common-container {
	border: 1px solid #ebeef5;
	border-radius: 8px;
	padding: 16px;
	background: #fafafa;
	box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}

/* 输入区域布局 */
.common-inputs {
	display: flex;
	gap: 10px;
	margin-bottom: 16px;
	flex-wrap: wrap;
}

.common-select {
	flex: 1;
	min-width: 180px;
}

.common-number-input {
	width: 120px;
}

.common-description-input {
	flex: 2;
	min-width: 280px;
}

.common-add-btn {
	flex-shrink: 0;
	height: 32px;
}

/* 列表样式 */
.common-list {
	display: flex;
	flex-direction: column;
	gap: 8px;
}

.common-item {
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding: 8px 12px;
	background: #fff;
	border-radius: 4px;
	border: 1px solid #ebeef5;
	transition: all 0.3s;
}

.common-item:hover {
	box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
	transform: translateY(-2px);
}

.item-text {
	flex: 1;
	margin-right: 12px;
	word-break: break-word;
}

.item-del-btn {
	flex-shrink: 0;
	margin-left: auto;
}

/* 响应式适配 */
@media (max-width: 768px) {
	.common-inputs {
		flex-direction: column;
	}

	.common-select,
	.common-number-input,
	.common-description-input {
		width: 100%;
	}
}

.attribute-list,
.effect-list {
	max-height: 400px;
	overflow-y: auto;
	padding: 8px;
}

.attribute-item,
.effect-item {
	padding: 6px 0;
	border-bottom: 1px solid #eee;
	&:last-child {
		border-bottom: none;
	}
}

.el-link {
	font-size: 13px;
	vertical-align: baseline;
}

.custom-close-btn {
	border: none !important;
	padding: 5px !important;
	transition: all 0.3s;

	&:hover {
		transform: rotate(90deg);
		color: #ff4d4f !important;
		background: rgba(255, 77, 79, 0.1) !important;
	}
}
</style>
